{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1bf0b43b-2a3a-446b-9c81-ff2b45f71297",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "!pip install -q cellxgene-census\n",
    "!pip install -q obonet"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "fc7994d3-f722-43e8-9a31-b16ab2022377",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.8/dist-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    }
   ],
   "source": [
    "from os.path import join\n",
    "\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "from tqdm.auto import tqdm"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "13b9f220-f20a-4e95-a6c0-30fb0662a0f7",
   "metadata": {},
   "source": [
    "# Utils code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2a8fd0f1-f5af-40f3-9ec5-8bf9cd711147",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import obonet\n",
    "import networkx\n",
    "\n",
    "\n",
    "url = 'http://purl.obolibrary.org/obo/cl/cl-simple.obo'\n",
    "graph = obonet.read_obo(url, ignore_obsolete=True)\n",
    "\n",
    "# only use \"is_a\" edges\n",
    "edges_to_delete = []\n",
    "for i, x in enumerate(graph.edges):\n",
    "    if x[2] != 'is_a':\n",
    "        edges_to_delete.append((x[0], x[1]))\n",
    "for x in edges_to_delete:\n",
    "    graph.remove_edge(u=x[0], v=x[1])\n",
    "\n",
    "# define mapping from id to name\n",
    "id_to_name = {id_: data.get('name') for id_, data in graph.nodes(data=True)}\n",
    "# define inverse mapping from name to id\n",
    "name_to_id = {v: k for k, v in id_to_name.items()}\n",
    "\n",
    "\n",
    "def find_child_nodes(cell_type):\n",
    "    return [id_to_name[node] for node in networkx.ancestors(graph, name_to_id[cell_type])]\n",
    "\n",
    "\n",
    "def find_parent_nodes(cell_type):\n",
    "    return [id_to_name[node] for node in networkx.descendants(graph, name_to_id[cell_type])]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6f47a0e9-71bb-4e5c-9c5a-4e0f1539cc8f",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "844d43c8-81be-4e1b-8b7a-e8832b59a963",
   "metadata": {},
   "source": [
    "# Select data to download"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "b528a064-0cc4-4bbf-b9c9-13a5e923e52c",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import cellxgene_census\n",
    "\n",
    "census = cellxgene_census.open_soma(census_version=\"2023-05-15\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "293868e7-c3a7-47be-baa4-a4e43ae9dafa",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "summary = census[\"census_info\"]['summary']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "45c58772-b4a3-4135-b70a-cb152b025215",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "PROTOCOLS = [\n",
    "    \"10x 5' v2\", \n",
    "    \"10x 3' v3\", \n",
    "    \"10x 3' v2\", \n",
    "    \"10x 5' v1\", \n",
    "    \"10x 3' v1\", \n",
    "    \"10x 3' transcription profiling\", \n",
    "    \"10x 5' transcription profiling\"\n",
    "]\n",
    "\n",
    "\n",
    "COLUMN_NAMES = [\n",
    "    \"soma_joinid\",\n",
    "    \"is_primary_data\",\n",
    "    \"dataset_id\", \n",
    "    \"donor_id\",\n",
    "    \"assay\", \n",
    "    \"cell_type\", \n",
    "    \"development_stage\", \n",
    "    \"disease\", \n",
    "    \"tissue\", \n",
    "    \"tissue_general\"\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "f660f1bc-33b4-42d5-92cf-eba62f066c60",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "obs = (\n",
    "    census[\"census_data\"][\"homo_sapiens\"]\n",
    "    .obs\n",
    "    .read(\n",
    "        column_names=COLUMN_NAMES,\n",
    "        value_filter=f\"is_primary_data == True and assay in {PROTOCOLS}\"\n",
    "    )\n",
    "    .concat()\n",
    "    .to_pandas()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "86654ff3-1991-4da3-a05d-4e1ffe25bdfa",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "obs['tech_sample'] = (obs.dataset_id + '_' + obs.donor_id).astype('category')\n",
    "\n",
    "for col in COLUMN_NAMES:\n",
    "    if obs[col].dtype == object:\n",
    "        obs[col] = obs[col].astype('category')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "66952771-6325-46b8-a4c6-7c61310bd50c",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "soma_joinid             int64\n",
       "is_primary_data          bool\n",
       "dataset_id           category\n",
       "donor_id             category\n",
       "assay                category\n",
       "cell_type            category\n",
       "development_stage    category\n",
       "disease              category\n",
       "tissue               category\n",
       "tissue_general       category\n",
       "tech_sample          category\n",
       "dtype: object"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "obs.dtypes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "13aeb3f1-de0e-4c87-a6a5-25463bf21851",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# remove all cell types which are not a subtype of native cell\n",
    "cell_types_to_remove = obs[~obs.cell_type.isin(find_child_nodes('native cell'))].cell_type.unique().tolist()\n",
    "\n",
    "# remove all cell types which have less than 5000 cells\n",
    "cell_freq = obs.cell_type.value_counts()\n",
    "cell_types_to_remove += cell_freq[cell_freq < 5000].index.tolist()\n",
    "\n",
    "# remove cell types which have less than 30 tech_samples\n",
    "tech_samples_per_cell_type = obs[['cell_type', 'tech_sample']].groupby('cell_type').agg({'tech_sample': 'nunique'}).sort_values('tech_sample')\n",
    "cell_types_to_remove += tech_samples_per_cell_type[tech_samples_per_cell_type.tech_sample <= 30].index.tolist()\n",
    "\n",
    "# filter out too granular labels\n",
    "# remove all cells that have <= 7 parents in the cell ontology\n",
    "cell_types = obs.cell_type.unique().tolist()\n",
    "\n",
    "n_children = []\n",
    "n_parents = []\n",
    "\n",
    "for cell_type in cell_types:\n",
    "    n_parents.append(len(find_parent_nodes(cell_type)))\n",
    "    n_children.append(len(find_child_nodes(cell_type)))\n",
    "\n",
    "cell_types_to_remove += (\n",
    "    pd.DataFrame({'n_children': n_children, 'n_parents': n_parents}, index=cell_types)\n",
    "    .query('n_parents <= 7')\n",
    "    .index.tolist()\n",
    ")\n",
    "cell_types_to_remove = list(set(cell_types_to_remove))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "cb63ed0f-970e-47da-99b1-fcdab300198b",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "164"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "obs.cell_type.nunique() - len(cell_types_to_remove)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "f90ec5d2-df39-4dc0-ad51-c4fca30d899c",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>soma_joinid</th>\n",
       "      <th>is_primary_data</th>\n",
       "      <th>dataset_id</th>\n",
       "      <th>donor_id</th>\n",
       "      <th>assay</th>\n",
       "      <th>cell_type</th>\n",
       "      <th>development_stage</th>\n",
       "      <th>disease</th>\n",
       "      <th>tissue</th>\n",
       "      <th>tissue_general</th>\n",
       "      <th>tech_sample</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>15</td>\n",
       "      <td>True</td>\n",
       "      <td>9d8e5dca-03a3-457d-b7fb-844c75735c83</td>\n",
       "      <td>donor-GOLD</td>\n",
       "      <td>10x 3' v3</td>\n",
       "      <td>macrophage</td>\n",
       "      <td>53-year-old human stage</td>\n",
       "      <td>normal</td>\n",
       "      <td>subcutaneous abdominal adipose tissue</td>\n",
       "      <td>adipose tissue</td>\n",
       "      <td>9d8e5dca-03a3-457d-b7fb-844c75735c83_donor-GOLD</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>16</td>\n",
       "      <td>True</td>\n",
       "      <td>9d8e5dca-03a3-457d-b7fb-844c75735c83</td>\n",
       "      <td>donor-GOLD</td>\n",
       "      <td>10x 3' v3</td>\n",
       "      <td>macrophage</td>\n",
       "      <td>53-year-old human stage</td>\n",
       "      <td>normal</td>\n",
       "      <td>subcutaneous abdominal adipose tissue</td>\n",
       "      <td>adipose tissue</td>\n",
       "      <td>9d8e5dca-03a3-457d-b7fb-844c75735c83_donor-GOLD</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>18</td>\n",
       "      <td>True</td>\n",
       "      <td>9d8e5dca-03a3-457d-b7fb-844c75735c83</td>\n",
       "      <td>donor-GOLD</td>\n",
       "      <td>10x 3' v3</td>\n",
       "      <td>endothelial cell</td>\n",
       "      <td>53-year-old human stage</td>\n",
       "      <td>normal</td>\n",
       "      <td>subcutaneous abdominal adipose tissue</td>\n",
       "      <td>adipose tissue</td>\n",
       "      <td>9d8e5dca-03a3-457d-b7fb-844c75735c83_donor-GOLD</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>19</td>\n",
       "      <td>True</td>\n",
       "      <td>9d8e5dca-03a3-457d-b7fb-844c75735c83</td>\n",
       "      <td>donor-GOLD</td>\n",
       "      <td>10x 3' v3</td>\n",
       "      <td>macrophage</td>\n",
       "      <td>53-year-old human stage</td>\n",
       "      <td>normal</td>\n",
       "      <td>subcutaneous abdominal adipose tissue</td>\n",
       "      <td>adipose tissue</td>\n",
       "      <td>9d8e5dca-03a3-457d-b7fb-844c75735c83_donor-GOLD</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>20</td>\n",
       "      <td>True</td>\n",
       "      <td>9d8e5dca-03a3-457d-b7fb-844c75735c83</td>\n",
       "      <td>donor-GOLD</td>\n",
       "      <td>10x 3' v3</td>\n",
       "      <td>macrophage</td>\n",
       "      <td>53-year-old human stage</td>\n",
       "      <td>normal</td>\n",
       "      <td>subcutaneous abdominal adipose tissue</td>\n",
       "      <td>adipose tissue</td>\n",
       "      <td>9d8e5dca-03a3-457d-b7fb-844c75735c83_donor-GOLD</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28169969</th>\n",
       "      <td>53794723</td>\n",
       "      <td>True</td>\n",
       "      <td>8c42cfd0-0b0a-46d5-910c-fc833d83c45e</td>\n",
       "      <td>3</td>\n",
       "      <td>10x 3' v2</td>\n",
       "      <td>pericyte</td>\n",
       "      <td>51-year-old human stage</td>\n",
       "      <td>normal</td>\n",
       "      <td>lung</td>\n",
       "      <td>lung</td>\n",
       "      <td>8c42cfd0-0b0a-46d5-910c-fc833d83c45e_3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28169970</th>\n",
       "      <td>53794724</td>\n",
       "      <td>True</td>\n",
       "      <td>8c42cfd0-0b0a-46d5-910c-fc833d83c45e</td>\n",
       "      <td>3</td>\n",
       "      <td>10x 3' v2</td>\n",
       "      <td>pericyte</td>\n",
       "      <td>51-year-old human stage</td>\n",
       "      <td>normal</td>\n",
       "      <td>lung</td>\n",
       "      <td>lung</td>\n",
       "      <td>8c42cfd0-0b0a-46d5-910c-fc833d83c45e_3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28169971</th>\n",
       "      <td>53794725</td>\n",
       "      <td>True</td>\n",
       "      <td>8c42cfd0-0b0a-46d5-910c-fc833d83c45e</td>\n",
       "      <td>3</td>\n",
       "      <td>10x 3' v2</td>\n",
       "      <td>pericyte</td>\n",
       "      <td>51-year-old human stage</td>\n",
       "      <td>normal</td>\n",
       "      <td>lung</td>\n",
       "      <td>lung</td>\n",
       "      <td>8c42cfd0-0b0a-46d5-910c-fc833d83c45e_3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28169972</th>\n",
       "      <td>53794726</td>\n",
       "      <td>True</td>\n",
       "      <td>8c42cfd0-0b0a-46d5-910c-fc833d83c45e</td>\n",
       "      <td>3</td>\n",
       "      <td>10x 3' v2</td>\n",
       "      <td>pericyte</td>\n",
       "      <td>51-year-old human stage</td>\n",
       "      <td>normal</td>\n",
       "      <td>lung</td>\n",
       "      <td>lung</td>\n",
       "      <td>8c42cfd0-0b0a-46d5-910c-fc833d83c45e_3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28169973</th>\n",
       "      <td>53794727</td>\n",
       "      <td>True</td>\n",
       "      <td>8c42cfd0-0b0a-46d5-910c-fc833d83c45e</td>\n",
       "      <td>3</td>\n",
       "      <td>10x 3' v2</td>\n",
       "      <td>pericyte</td>\n",
       "      <td>51-year-old human stage</td>\n",
       "      <td>normal</td>\n",
       "      <td>lung</td>\n",
       "      <td>lung</td>\n",
       "      <td>8c42cfd0-0b0a-46d5-910c-fc833d83c45e_3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>22190622 rows × 11 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "          soma_joinid  is_primary_data                            dataset_id   \n",
       "15                 15             True  9d8e5dca-03a3-457d-b7fb-844c75735c83  \\\n",
       "16                 16             True  9d8e5dca-03a3-457d-b7fb-844c75735c83   \n",
       "18                 18             True  9d8e5dca-03a3-457d-b7fb-844c75735c83   \n",
       "19                 19             True  9d8e5dca-03a3-457d-b7fb-844c75735c83   \n",
       "20                 20             True  9d8e5dca-03a3-457d-b7fb-844c75735c83   \n",
       "...               ...              ...                                   ...   \n",
       "28169969     53794723             True  8c42cfd0-0b0a-46d5-910c-fc833d83c45e   \n",
       "28169970     53794724             True  8c42cfd0-0b0a-46d5-910c-fc833d83c45e   \n",
       "28169971     53794725             True  8c42cfd0-0b0a-46d5-910c-fc833d83c45e   \n",
       "28169972     53794726             True  8c42cfd0-0b0a-46d5-910c-fc833d83c45e   \n",
       "28169973     53794727             True  8c42cfd0-0b0a-46d5-910c-fc833d83c45e   \n",
       "\n",
       "            donor_id      assay         cell_type        development_stage   \n",
       "15        donor-GOLD  10x 3' v3        macrophage  53-year-old human stage  \\\n",
       "16        donor-GOLD  10x 3' v3        macrophage  53-year-old human stage   \n",
       "18        donor-GOLD  10x 3' v3  endothelial cell  53-year-old human stage   \n",
       "19        donor-GOLD  10x 3' v3        macrophage  53-year-old human stage   \n",
       "20        donor-GOLD  10x 3' v3        macrophage  53-year-old human stage   \n",
       "...              ...        ...               ...                      ...   \n",
       "28169969           3  10x 3' v2          pericyte  51-year-old human stage   \n",
       "28169970           3  10x 3' v2          pericyte  51-year-old human stage   \n",
       "28169971           3  10x 3' v2          pericyte  51-year-old human stage   \n",
       "28169972           3  10x 3' v2          pericyte  51-year-old human stage   \n",
       "28169973           3  10x 3' v2          pericyte  51-year-old human stage   \n",
       "\n",
       "         disease                                 tissue  tissue_general   \n",
       "15        normal  subcutaneous abdominal adipose tissue  adipose tissue  \\\n",
       "16        normal  subcutaneous abdominal adipose tissue  adipose tissue   \n",
       "18        normal  subcutaneous abdominal adipose tissue  adipose tissue   \n",
       "19        normal  subcutaneous abdominal adipose tissue  adipose tissue   \n",
       "20        normal  subcutaneous abdominal adipose tissue  adipose tissue   \n",
       "...          ...                                    ...             ...   \n",
       "28169969  normal                                   lung            lung   \n",
       "28169970  normal                                   lung            lung   \n",
       "28169971  normal                                   lung            lung   \n",
       "28169972  normal                                   lung            lung   \n",
       "28169973  normal                                   lung            lung   \n",
       "\n",
       "                                              tech_sample  \n",
       "15        9d8e5dca-03a3-457d-b7fb-844c75735c83_donor-GOLD  \n",
       "16        9d8e5dca-03a3-457d-b7fb-844c75735c83_donor-GOLD  \n",
       "18        9d8e5dca-03a3-457d-b7fb-844c75735c83_donor-GOLD  \n",
       "19        9d8e5dca-03a3-457d-b7fb-844c75735c83_donor-GOLD  \n",
       "20        9d8e5dca-03a3-457d-b7fb-844c75735c83_donor-GOLD  \n",
       "...                                                   ...  \n",
       "28169969           8c42cfd0-0b0a-46d5-910c-fc833d83c45e_3  \n",
       "28169970           8c42cfd0-0b0a-46d5-910c-fc833d83c45e_3  \n",
       "28169971           8c42cfd0-0b0a-46d5-910c-fc833d83c45e_3  \n",
       "28169972           8c42cfd0-0b0a-46d5-910c-fc833d83c45e_3  \n",
       "28169973           8c42cfd0-0b0a-46d5-910c-fc833d83c45e_3  \n",
       "\n",
       "[22190622 rows x 11 columns]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "obs_subset = obs[~obs.cell_type.isin(cell_types_to_remove)].copy()\n",
    "for col in obs_subset.columns:\n",
    "    if obs_subset[col].dtype == 'category':\n",
    "        obs_subset[col] = obs_subset[col].cat.remove_unused_categories()\n",
    "obs_subset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "7ed30bb6-28bb-42f1-bade-557c0958b51d",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "cell_types_to_keep = obs_subset.cell_type.unique().tolist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "76f96ce9-f18c-4698-a572-29bd08ee3862",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "356d8a14-79af-420d-9ecf-71add45acb65",
   "metadata": {
    "tags": []
   },
   "source": [
    "# Download data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "374a77b2-cdf2-4e1c-8c60-ed280adb5541",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "protein_coding_genes = pd.read_parquet('features.parquet').gene_names.tolist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2ac6cb93-7c4a-4375-b0cf-d14889673ef2",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "19it [19:39:25, 3355.84s/it]"
     ]
    }
   ],
   "source": [
    "BASE_PATH = '/mnt/dssfs02/cxg_census/h5ad_raw_2023_05_15'\n",
    "\n",
    "\n",
    "# download in batches to not run out of memory\n",
    "for i, idxs in tqdm(enumerate(np.array_split(obs_subset.soma_joinid.to_numpy(), 20))):\n",
    "    adata = cellxgene_census.get_anndata(\n",
    "        census=census,\n",
    "        organism=\"Homo sapiens\",\n",
    "        X_name='raw',\n",
    "        obs_coords=idxs.tolist(),\n",
    "        var_value_filter=f\"feature_name in {protein_coding_genes}\",\n",
    "        column_names={\"obs\": COLUMN_NAMES, \"var\": ['feature_id', 'feature_name']},\n",
    "    )\n",
    "    adata.write_h5ad(join(BASE_PATH, f'{i}.h5ad'))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "411127d8-45e5-409e-988c-bbed4eb4a033",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
